package com.zoe.app.intercept;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ReUtil;
import org.springframework.http.HttpMethod;
import org.springframework.stereotype.Component;
import org.springframework.util.MultiValueMap;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import org.springframework.web.multipart.support.StandardMultipartHttpServletRequest;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.Method;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * @author Zoe.Zhang
 * @date 2021/10/10
 * @description
 */
@Component
public class DynamicIntercept implements HandlerInterceptor {

    public static boolean getFileTypeGroup(String fileName) {
        String office = ".+(.doc|.docx|.wps|.pdf)$";
        String image = ".+(.bmp|.jpg|.wps|.jpeg|.png|.gif)$";
        String video = ".+(.avi|.wmv|.mpg|.mpeg|.mov|.rm|.ram|.swf|.flv|.mp4)$";

        if (ReUtil.contains(office, fileName) || ReUtil.contains(image, fileName) || ReUtil.contains(video, fileName)) {
            return true;
        }
        return false;

    }

    /**
     * 请求到达之前处理的逻辑;比如是否登录这样;返回false请求将中断,不再继续往下执行;返回true则不会有影响
     *
     * @param request
     * @param response
     * @param handler  // https://www.cnblogs.com/leftthen/p/5229204.html 可以拿到接口方法中的信息
     * @return
     * @throws Exception
     */
    @Override
    public boolean preHandle(HttpServletRequest request,
                             HttpServletResponse response,
                             Object handler) throws Exception {
        // 有些资源请求也会被拦截下来,但是他们不是一个HandlerMethod,就直接放行处理
        if (!(handler instanceof HandlerMethod)) {
            return true;
        }
        if (HttpMethod.POST.name().equals(request.getMethod()) && request instanceof MultipartHttpServletRequest) {
            StandardMultipartHttpServletRequest request1 = (StandardMultipartHttpServletRequest) request;
            MultiValueMap<String, MultipartFile> multiFileMap = request1.getMultiFileMap();
            Set<Map.Entry<String, List<MultipartFile>>> entries = multiFileMap.entrySet();
            for (Map.Entry<String, List<MultipartFile>> entry : entries) {
                String key = entry.getKey();
                System.out.println("文件key===" + key);
                List<MultipartFile> entryValue = entry.getValue();
                for (MultipartFile multipartFile : entryValue) {
                    String originalFilename = multipartFile.getOriginalFilename();
                    boolean fileTypeGroup = getFileTypeGroup(originalFilename);
                    if (!fileTypeGroup) {
                        throw new RuntimeException("无效的文件类型");
                    }
                }
            }
        }
        // 获取拦截到的接口方法
        HandlerMethod handler1 = (HandlerMethod) handler;
        Method method = handler1.getMethod();
        System.out.println(method.toString());
        System.out.println("DynamicIntercept#DynamicIntercept#preHandle===>" + DateUtil.date() + "====>" + Thread.currentThread().getName());
        return true;
    }

    /**
     * 请求处理完成之后;Controller执行完成之后调用
     *
     * @param request
     * @param response
     * @param handler
     * @param modelAndView
     * @throws Exception
     */
    @Override
    public void postHandle(HttpServletRequest request,
                           HttpServletResponse response,
                           Object handler,
                           ModelAndView modelAndView) throws Exception {
        System.out.println("DynamicIntercept#postHandle===>" + DateUtil.date() + "====>" + Thread.currentThread().getName());
    }

    /**
     * 只会在preHandel返回True该方法才会执行;可以做一些清理资源的操作
     *
     * @param request
     * @param response
     * @param handler
     * @param ex
     * @throws Exception
     */
    @Override
    public void afterCompletion(HttpServletRequest request,
                                HttpServletResponse response,
                                Object handler,
                                Exception ex) throws Exception {
        System.out.println("DynamicIntercept#afterCompletion===>" + DateUtil.date() + "====>" + Thread.currentThread().getName());
    }
}
